Ext.ux.LiveDataPanel = Ext.extend(Ext.Panel, {
	limit: 10,
	currPage: 0,
	loadingTxt: Ext.LoadMask.prototype.msg,
	loadingIndicatorTxt: '{0} of {1} entries',
	loading: false,
	triggerScrollOffset: 150,
	initComponent: function(){
		var offset = this.frame ? 35 : 20;
		this.autoScroll = true;
		this.items = [{
			itemId: 'dv',
			xtype: 'dataview',
			autoScroll: true,
			width: this.width - offset,
			tpl: this.tpl,
			store: this.store,
			itemSelector: this.itemSelector
		}];
		Ext.ux.LiveDataPanel.superclass.initComponent.call(this);
		this.dv = this.getComponent('dv');
	},
	onRender: function(ct, pos){
		Ext.ux.LiveDataPanel.superclass.onRender.apply(this, arguments);
		this.indicatorEl = this.el.createChild({
			tag: 'div',
			cls: 'load-indicator',
			html: '<img src="loader.gif" /><span></span>'
		});
		this.dv.store.on('load', function(){
			this.indicatorEl.anchorTo(this.el, 'br-br?', [-25, -10]);
		}, this);
		this.body.on('scroll', function(e, t){
			var ds = this.dv.store;
			if ((t.scrollTop + t.clientHeight + this.triggerScrollOffset >= t.scrollHeight) && ds.getCount() !== ds.getTotalCount() && this.loading === false) {					
				this.nextPage();				
			}
		}, this);
	},
	nextPage: function(pageNum) {		
		this.currPage++;
		this.updateIndicator();
		this.indicatorEl.show();		
		var start = this.currPage * this.limit;			
		this.loading = true;
		this.dv.store.load({
			params: {
				start: start,
				limit: this.limit					
			},
			callback: function() {
				this.indicatorEl.hide();					
				this.loading = false;
			},
			scope: this,
			add: true
		});
	},
	updateIndicator: function() {
		var txt = String.format(this.loadingIndicatorTxt, this.currPage * this.limit, this.dv.store.getTotalCount());
		this.indicatorEl.down('span').update(txt);
	}
});
Ext.reg('livedatapanel', Ext.ux.LiveDataPanel);

Ext.DataView.override({
    onAdd : function(ds, records, index){
        if(this.all.getCount() == 0){
            this.refresh();
            return;
        }
        var nodes = this.bufferRender(records, index), n, a = this.all.elements;		
        if(index < this.all.getCount()){
            n = this.all.item(index).insertSibling(nodes, 'before', true);
            a.splice.apply(a, [index, 0].concat(nodes));
        }else{
			nodes.reverse();
            n = this.all.last().insertSibling(nodes, 'after', true);
			nodes.reverse();
            a.push.apply(a, nodes);
        }
        this.updateIndexes(index);
    }
});